package com.ginmeta.service.system;

import cn.hutool.core.util.RandomUtil;
import com.ginmeta.common.utils.StringUtils;
import com.ginmeta.domain.system.entity.SysUser;
import com.ginmeta.domain.system.entity.SysUserRole;
import com.ginmeta.domain.system.vo.UserDetailRespVO;
import com.ginmeta.domain.system.vo.UserPageReqVO;
import com.ginmeta.mapper.system.SysUserMapper;
import com.ginmeta.mapper.system.SysUserRoleMapper;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 用户业务层
 *
 * @author GinMeta
 */
@Slf4j
@Service
public class SysUserService extends ServiceImpl<SysUserMapper, SysUser> {

    @Resource
    private SysUserRoleMapper sysUserRoleMapper;

    /**
     * 查询用户列表
     *
     * @param reqVO 参数
     * @return 结果
     */
    public Page<UserDetailRespVO> selectUserList(UserPageReqVO reqVO, Page<UserDetailRespVO> page) {
        return mapper.paginateAs(page, QueryWrapper.create()
                        .select()
                        .from(SysUser.class)
                        .where(SysUser::getUsername).like(reqVO.getUsername(), StringUtils::isNotBlank)
                        .and(SysUser::getNickName).like(reqVO.getNickName(), StringUtils::isNotBlank)
                        .and(SysUser::getPhone).like(reqVO.getPhone(), StringUtils::isNotBlank)
                        .and(SysUser::getEmail).like(reqVO.getEmail(), StringUtils::isNotBlank)
                        .and(SysUser::getGender).eq(reqVO.getGender(), StringUtils::isNotBlank)
                        .orderBy(SysUser::getRegistrationDate).desc()
                        .orderBy(SysUser::getUsername).asc()
                , UserDetailRespVO.class);
    }

    /**
     * 新增用户
     *
     * @param sysUser 参数
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean add(SysUser sysUser) {
        // 新增用户
        boolean result = this.save(sysUser);
        if (result) {
            SysUser su = this.getOne(new QueryWrapper().where(SysUser::getUsername).eq(sysUser.getUsername()));
            sysUser.setUserId(su.getUserId());
            // 新增用户与角色关系
            insertUserRole(sysUser);
        }
        return result;
    }

    /**
     * 修改用户
     *
     * @param sysUser 参数
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean edit(SysUser sysUser) {
        // 新增用户
        boolean result = this.updateById(sysUser);
        // 删除用户与角色关系
        removeUserRole(sysUser.getUserId());
        // 新增用户与角色关系
        insertUserRole(sysUser);
        return result;
    }

    /**
     * 获取随机昵称
     *
     * @return 昵称
     */
    public String getRandomNickName() {
        String nickName = null;
        while (StringUtils.isBlank(nickName) || this.checkNickNameUnique(nickName)) {
            nickName = RandomUtil.randomString(8);
        }
        return nickName;
    }

    /**
     * 校验用户名是否存在
     *
     * @param username 用户名
     * @return 结果
     */
    public boolean checkUsernameUnique(String username) {
        SysUser sysUser = this.getOne(new QueryWrapper()
                .where(SysUser::getUsername).eq(username)
        );
        return StringUtils.isNotNull(sysUser);
    }

    /**
     * 校验昵称是否存在
     *
     * @param nickName 昵称
     * @return 结果
     */
    public boolean checkNickNameUnique(String nickName) {
        SysUser sysUser = this.getOne(new QueryWrapper()
                .where(SysUser::getNickName).eq(nickName)
        );
        return StringUtils.isNotNull(sysUser);
    }

    /**
     * 校验邮箱是否存在
     *
     * @param email 邮箱
     * @return 结果
     */
    public boolean checkEmailUnique(String email) {
        SysUser sysUser = this.getOne(new QueryWrapper()
                .where(SysUser::getEmail).eq(email)
        );
        return StringUtils.isNotNull(sysUser);
    }

    /**
     * 校验手机号是否存在
     *
     * @param phone 手机号
     * @return 结果
     */
    public boolean checkPhoneUnique(String phone) {
        // 根据手机号查询用户
        SysUser sysUser = this.getOne(new QueryWrapper()
                .where(SysUser::getPhone).eq(phone)
        );
        return StringUtils.isNotNull(sysUser);
    }

    /**
     * 新增用户角色信息
     *
     * @param user 用户对象
     */
    public void insertUserRole(SysUser user) {
        this.insertUserRole(user.getUserId(), user.getRoleIds());
    }

    /**
     * 新增用户角色信息
     *
     * @param userId  用户ID
     * @param roleIds 角色组
     */
    public void insertUserRole(Long userId, List<Long> roleIds) {
        if (StringUtils.isNotEmpty(roleIds)) {
            // 新增用户与角色管理
            List<SysUserRole> list = new ArrayList<>(roleIds.size());
            for (Long roleId : roleIds) {
                SysUserRole ur = new SysUserRole();
                ur.setUserId(userId);
                ur.setRoleId(roleId);
                list.add(ur);
            }
            sysUserRoleMapper.batchUserRole(list);
        }
    }

    /**
     * 根据用户id删除用户角色信息
     *
     * @param userId 用户id
     */
    public void removeUserRole(Long userId) {
        if (StringUtils.isNotNull(userId)) {
            sysUserRoleMapper.deleteByQuery(new QueryWrapper().where(SysUserRole::getUserId).eq(userId));
        }
    }

    /**
     * 根据用户id删除用户角色信息
     *
     * @param userIds 用户id
     */
    public void removeUserRoleList(List<Long> userIds) {
        if (StringUtils.isNotEmpty(userIds)) {
            sysUserRoleMapper.deleteByQuery(new QueryWrapper().where(SysUserRole::getUserId).in(userIds));
        }
    }
}
